﻿using System.Linq.Expressions;

namespace Lingmeng.EntityFrameworkCore.Extensions;

public static class QueryableExtensions
{
    //接受三个参数：一个 IQueryable<T> 对象、一个整数类型的 skipCount （表示跳过的结果数量），
    //以及一个整数类型的 maxResultCount （表示最大返回的结果数量）。

    //该方法的作用是将 IQueryable<T> 对象进行分页处理，并返回一个经过分页处理后的 IQueryable<T> 对象。
    //具体实现方式是通过 Skip 和 Take 方法来实现。其中，Skip 方法用于跳过指定数量的数据行，
    //Take 方法用于从剩余的数据行中获取指定数量的数据行
    public static IQueryable<T> PageBy<T>(
        this IQueryable<T> query,
        int skipCount,
        int maxResultCount)
    {
        return query.Skip(skipCount).Take(maxResultCount);
    }
    //同上，这个方法支持对 IQueryable<T> 的任何子类型进行分页处理，而不仅仅是 IQueryable<T> 类型本身
    public static TQueryable PageBy<T, TQueryable>(
        this TQueryable query,
        int skipCount,
        int maxResultCount)
        where TQueryable : IQueryable<T>
    {
        return (TQueryable)query.Skip(skipCount).Take(maxResultCount);
    }
    //根据条件动态添加 Where 子句来筛选 IQueryable<T> 对象。如果条件 condition 为 true，
    //则使用传入的 predicate 表达式进行筛选；否则直接返回原始 IQueryable<T> 对象
    public static IQueryable<T> WhereIf<T>(
        this IQueryable<T> query,
        bool condition,
        Expression<Func<T, bool>> predicate)
    {
        return !condition ? query : query.Where(predicate);
    }
    //同上，不同之处在于，这个方法支持对 IQueryable<T> 的任何子类型进行筛选。
    public static TQueryable WhereIf<T, TQueryable>(
        this TQueryable query,
        bool condition,
        Expression<Func<T, bool>> predicate)
        where TQueryable : IQueryable<T>
    {
        return !condition ? query : (TQueryable)query.Where<T>(predicate);
    }
    //不同之处在于，这个方法支持在 predicate 表达式中访问每个元素的索引值
    public static IQueryable<T> WhereIf<T>(
        this IQueryable<T> query,
        bool condition,
        Expression<Func<T, int, bool>> predicate)
    {
        return !condition ? query : query.Where(predicate);
    }

    public static TQueryable WhereIf<T, TQueryable>(
        this TQueryable query,
        bool condition,
        Expression<Func<T, int, bool>> predicate)
        where TQueryable : IQueryable<T>
    {
        return !condition ? query : (TQueryable)query.Where<T>(predicate);
    }

}